package webx.http;

import stdx.Utils;
import java.util.Set;
import webx.json.JsonObject;
import java.lang.reflect.Field;

public class HttpRequest{
	byte[] body = null;
	HttpHeadNode head = new HttpHeadNode();
	HttpDataNode data = new HttpDataNode();
	
	public HttpRequest(){
	}
	public HttpRequest(byte[] msg){
		parse(msg);
	}
	public boolean parse(byte[] msg){
		int pos = 0;
		int end = -1;
		final byte r = '\r';
		final byte n = '\n';

		end = msg.length;

		while (true){
			while (pos < end){
				if (msg[pos] == r) break;
				++pos;
			}

			if (pos >= end || pos + 4 > end) return false;

			if (msg[pos + 1] == n && msg[pos + 2] == r && msg[pos + 3] == n){
				body = new byte[end - pos - 4];
				System.arraycopy(msg, pos + 4, body, 0, body.length);

				head.parse(new String(msg, 0, pos));
				data.parse(new String(body));

				return true;
			}

			pos++;
		}
	}

	public byte[] getBody(){
		if (body == null){
			try{
				body = data.toString().getBytes(Http.GetCharset());
			}
			catch(Exception e){
                e.printStackTrace();
			}
		}

		return body;
	}
	public Set<String> getKeys(){
		return data.getKeys();
	}
	public String get(String key){
		return data.get(key);
	}
	public void set(String key, String val){
		data.set(key, val);
		body = null;
	}
	public <T> T toObject(Class<T> clazz) throws InstantiationException, IllegalAccessException{
	    T obj = clazz.newInstance();

        if (body == null || body.length <= 0) return obj;

        String msg = new String(body).trim();
        Field[] fields = clazz.getDeclaredFields();

        if (msg.startsWith("{") && msg.endsWith("}")){
            JsonObject json = new JsonObject(msg);

            for (Field field : fields) Utils.InitFieldValue(field, obj, json.asString(field.getName()));
        }
        else{
            for (Field field : fields) Utils.InitFieldValue(field, obj, get(field.getName()));
        }

        return obj;
    }

    public Set<String> getHeadKeys(){
        return head.getKeys();
    }
    public String getHeader(String key){
        return head.get(key);
    }
    public void setHeader(String key, String val){
        head.set(key, val);
    }
}